package com.supreme.studyserver.aspect;

import com.supreme.studyserver.threadstore.ThreadStore;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

@Aspect
@Component
public class MissingYouAspect {

    @Resource
    private HttpServletRequest httpServletRequest;

    /**
     * @target(com.supreme.studyserver.annotation.MissingYou)
     * @within(com.supreme.studyserver.annotation.MissingYou): 注解作用在类上面
     * @annotation(com.supreme.studyserver.annotation.MissingYou):  注解作用在方法上面
     */
    @Pointcut(value = "@annotation(com.supreme.studyserver.annotation.MissingYou)")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void beforeProcess(JoinPoint joinPoint) {
        final String threadName = Thread.currentThread().getName();
        System.out.println("Before ========================================: " + threadName);
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();

        String clientId = httpServletRequest.getHeader("clientId");
        System.out.println("clientId: " + clientId);
        ThreadStore.setStore(Integer.valueOf(clientId));

        System.out.println("Around Before ========================================");
        Object proceed = null;
        try {
            proceed = proceedingJoinPoint.proceed();
            System.out.println("Around After ========================================");
        } catch (Throwable e) {
            System.out.println("Around Throwable ======================================== " + e.getMessage());
        }

        stopWatch.stop();
        System.out.println(stopWatch.getTotalTimeMillis() + "ms");
        ThreadStore.removeStore();
        return proceed;
    }

    @After("pointcut()")
    public void afterProcess(JoinPoint joinPoint) {
        final String threadName = Thread.currentThread().getName();
        System.out.println("After ========================================: " + threadName);
        ThreadStore.printStoreInfo();
        ThreadStore.printThreadInfo();

    }

    @AfterReturning(pointcut = "pointcut()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("AfterReturning ======================================== " + result);
    }

    @AfterThrowing(pointcut = "pointcut()", throwing = "exception")
    public void afterThrowing(Throwable exception) {
        System.out.println("AfterThrowing ======================================== " + exception.getMessage());
    }
}
